package template.dao;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import java.util.List;
import java.util.Map;

import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.transform.Transformers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;


/**
 * 数据库操作基类,其他所有数据库操作类均须继承该类。 本类定义了数据库操作的基本方法。 其他类只需继承该类即可。
 * 
 * @author smy
 * @version 1.0
 */
public class BaseDaoImpl extends HibernateDaoSupport implements IBaseDao {
	
	@Autowired
	public void setSessionFactory1(SessionFactory sessionFactory) {
		super.setSessionFactory(sessionFactory);
	}

	/**
	 * 根据hql语句获取记录数
	 * 
	 * @param hql语句
	 * @return 记录数，整型
	 */
	public int getTotal(String hql) {
		List result = this.getHibernateTemplate().find(hql);
		if (null != result && !result.isEmpty()) {
			return ((Long) result.get(0)).intValue();
		}

		return 0;
	}

	/**
	 * 保存记录
	 */
	public void save(Object obj) {
		this.getHibernateTemplate().save(obj);
	}

	/**
	 * 更新记录
	 */
	public void update(Object obj) {
		this.getHibernateTemplate().update(obj);
	}

	/**
	 * 删除记录
	 */
	public void remove(Object obj) {
		this.getHibernateTemplate().delete(obj);
	}

	/**
	 * 由主键获取一条记录
	 */
	public <T> T findById(Serializable id, Class<T> className) {
		@SuppressWarnings("unchecked")
		T t = (T) this.getHibernateTemplate().get(className, id);
		return t;
	}
	
	/**
	 * 由hql语句获取记录列表。
	 * 
	 * @param hql
	 *            hql语句
	 * @return 保存结果的List
	 */
	public <T> List<T> getRecordList(String hql) {
		@SuppressWarnings("unchecked")
		List<T> list = this.getHibernateTemplate().find(hql);
		return list;
	}

	/**
	 * 由hql语句获取记录列表。
	 * 
	 * @param hql
	 *            hql语句
	 * @return 保存结果的List
	 */
	public <T> List<T> getRecordList(final String hql, final int beginIndex,
			final int recordLen) {
		
		@SuppressWarnings("unchecked")
		List<T> executeFind = getHibernateTemplate().executeFind(new HibernateCallback() {
							public Object doInHibernate(Session s) throws HibernateException,
									SQLException {
								return s.createQuery(hql).setFirstResult(beginIndex)
										.setMaxResults(recordLen).list();
							}
						});
		return executeFind;
	}

	/**
	 * 判断某个对象是否存在
	 */
	public boolean checkExist(Object object) {
		return this.getHibernateTemplate().contains(object);
	}

	/**
	 * 使用sql进行查询
	 */
	public <T> List<T> queryBySql(final String sql, final Class<T> clazz,
			final int firstResult, final int maxResults) {

		@SuppressWarnings("unchecked")
		List<T> executeFind = getHibernateTemplate().executeFind(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {

						SQLQuery query = session.createSQLQuery(sql);
						/*for (Field field : clazz.getDeclaredFields()) { // 遍历类中的所有属性
							query.addScalar(field.getName(), TypeFactory
									.basic(field.getType().getName()));
						}*/
						return query.setResultTransformer(
								Transformers.aliasToBean(clazz))
								.setFirstResult(firstResult).setMaxResults(
										maxResults).list();
					}
				});
		return executeFind;

	}

	/**
	 * 使用sql进行查询
	 */
	public <T> List<T> queryBySql(final String sql, final Class<T> clazz) {

		@SuppressWarnings("unchecked")
		List<T> executeFind = getHibernateTemplate().executeFind(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						SQLQuery query = session.createSQLQuery(sql);
						/*for (Field field : clazz.getDeclaredFields()) { // 遍历类中的所有属性
							query.addScalar(field.getName(), TypeFactory
									.basic(field.getType().getName()));
						}*/
						return query.setResultTransformer(
								Transformers.aliasToBean(clazz)).list();
					}
				});
		return executeFind;

	}

	public List<Map> query(final String sql) {

		@SuppressWarnings("unchecked")
		List<Map> executeFind = getHibernateTemplate().executeFind(
				new HibernateCallback() {

					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {

						return session.createSQLQuery(sql)
								.setResultTransformer(
										Transformers.ALIAS_TO_ENTITY_MAP)
								.list();

					}

				});
		return executeFind;
	}

	public List<Map> query(final String sql, final int firstResult,
			final int maxResults) {

		@SuppressWarnings("unchecked")
		List<Map> executeFind = getHibernateTemplate().executeFind(
				new HibernateCallback() {

					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {

						return session.createSQLQuery(sql)
								.setResultTransformer(
										Transformers.ALIAS_TO_ENTITY_MAP)
								.setFirstResult(firstResult).setMaxResults(
										maxResults).list();

					}

				});
		return executeFind;
	}

	/**
	 * 使用hql语句进行批量添加,修改和删除
	 * 
	 * @param Hql
	 *            hql语句
	 * @return 操作影响的个数
	 */
	public int updateByHql(String hql) {
		return this.getHibernateTemplate().bulkUpdate(hql);
	}

	/**
	 * 使用sql语句获取对象个数
	 * 
	 * @param countSql
	 *            能查詢个数的sql語句, 形如：select count（*）as count,注意一定要用count作为返回的别名
	 * @return 对象个数
	 */
	public int getTotalBySql(final String sql) {

		return (Integer) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {

						return session.createSQLQuery(sql).addScalar(
								"count", Hibernate.INTEGER).uniqueResult();

					}
				});
	}

	/**
	 * 使用jdbc进行各种数据库的操作
	 * 
	 * @param sql
	 *            sql语句
	 */
	public void executeByJdbc(final String sql) {

		getHibernateTemplate().execute(new HibernateCallback() {
			
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {

				@SuppressWarnings("deprecation")
				Connection conn = session.connection();
				Statement st = conn.createStatement();
				st.execute(sql);
				System.out.println("sql:" + sql);
				st.close();
				conn.close();

				return null;
			}
		});
	}

}
